/***************************************************************************
 *   Copyright (C) 2009 by Eric Maeker, MD.                                *
 *   eric.maeker@free.fr                                                   *
 *   and modified for his purpose by Pierre-Marie Desombre, GP,            *
 *   pm.desombre@medsyn.fr                                                 *
 *   This code is free and open source .                                   *
 *   It is released under the terms of the new BSD License.                *
 *                                                                         *
 *   Redistribution and use in source and binary forms, with or without    *
 *   modification, are permitted provided that the following conditions    *
 *   are met:                                                              *
 *   - Redistributions of source code must retain the above copyright      *
 *   notice, this list of conditions and the following disclaimer.         *
 *   - Redistributions in binary form must reproduce the above copyright   *
 *   notice, this list of conditions and the following disclaimer in the   *
 *   documentation and/or other materials provided with the distribution.  *
 *   - Neither the name of the FreeMedForms' organization nor the names of *
 *   its contributors may be used to endorse or promote products derived   *
 *   from this software without specific prior written permission.         *
 *                                                                         *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS     *
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  *
 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
 *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      *
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER      *
 *   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT    *
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN     *
 *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
 *   POSSIBILITY OF SUCH DAMAGE.                                           *
 ***************************************************************************/
 /***************************************************************************
 *   Main Developper : Eric MAEKER, <eric.maeker@free.fr>                  *
 *   Contributors :                                                        *
 *       Docteur Pierre-Marie Desombre,pm.desombre@medsyn.fr               *
 ***************************************************************************/
#include "databasemanager.h"
#include <common/constants.h>
#include <QProgressDialog>
#include <QMessageBox>
#include <QString>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QApplication>
#include <QtSql>
#include <QDebug>
#include <QCursor>

using namespace Common;
using namespace Constants;


DatabaseManager::DatabaseManager(QObject *parent) :
        QObject(parent),
        m_IsBmiConfigured(false)

{
    set = new settings;
}

DatabaseManager::~DatabaseManager()
{
    delete set;
}

bool DatabaseManager::connectBmisurvey()
{
    QString database = set->value(Constants::DATABASE_BMISURVEY).toString();
    QString log    = set->value(Constants::USER_BMISURVEY).toString();
    QString pass   = set->value(PASSWORD_BMISURVEY).toString();
    QString host   = set->value(Constants::HOST_BMISURVEY).toString();
    QString port   = set->value(PORT_BMISURVEY).toString();
    
    //--------------------------------------
    //test dir sqliteBase exists
    QDir sqliteBaseDir(set->databasePath());
    if (!sqliteBaseDir.exists())
    {
    	  if (!sqliteBaseDir.mkdir(set->databasePath()))
    	  {
    	  	  qWarning() << __FILE__ << QString::number(__LINE__) << "UNABLE TO CREATE "
    	  	  << set->databasePath() ;
    	  	  return false;
    	      }
        }
    QSqlDatabase db;
    bool dbTest = 0;
 
            db = QSqlDatabase::addDatabase("QSQLITE", Constants::DATABASE_BMISURVEY);
            db.setDatabaseName(set->databasePath() + QDir::separator() + database + ".db");
            db.setHostName(host);
            db.setUserName(log);
            db.setPassword(pass);
                qWarning() << "Connecting bmisurvey database SQLite " + db.databaseName() 
                              +" "+QString(__LINE__)
                              +" "+ QString::number(__LINE__);

            if(!db.open()){
                qWarning() << __FILE__ << QString::number(__LINE__) << " database bmisurvey cannot open";
            }
            QStringList tables = db.tables();
            qDebug() << __FILE__ << QString::number(__LINE__)<< " tables "+QString::number(tables.size());
            dbTest = (tables.size() < 1);

    if (dbTest) {
        if (!createBmisurveyDatabaseSchema("QSQLITE")) {
            QMessageBox::warning(qApp->activeWindow(),
                                 tr("Fatal error"),
                                 tr("Unable to connect bmisurvey database. Application will not work."),
                                 QMessageBox::Abort);
            qWarning() << "FATAL ERROR : Unable to create the bmisurvey database" 
                       << __FILE__
                       << QString::number(__LINE__);
            return false;
        }
        else {
            
                qWarning() << "Connected to bmisurvey database"
                           << db.databaseName()
                           << __FILE__
                           << QString::number(__LINE__);
                m_IsBmiConfigured = true;
        }
        return false;
    }
    return true;
}

bool DatabaseManager::createBmisurveyDatabase(const QString & driver) const
{
    if (driver== "QSQLITE")
        return true;
    QSqlDatabase dbFirst = QSqlDatabase::database(Constants::DATABASE_BMISURVEY);
    QString reqForA = "CREATE DATABASE bmisurvey";
    QSqlQuery q(dbFirst);
    q.exec(reqForA);
    if (q.lastError().isValid() == true) {
        QMessageBox::warning(qApp->activeWindow(),
                             tr("Fatal error"),
                             tr("An error occured during bmisurvey database creation.\n")
                             +__FILE__+" "+QString::number(__LINE__),
                             QMessageBox::Abort);
        qWarning() << "SQL Error" << q.lastError().text() 
                   << __FILE__ << QString::number(__LINE__);
        return false;
    }
    return true;
}


bool DatabaseManager::createBmisurveyDatabaseSchema(const QString & driver)
{
    bool result = true;
    if ((driver!= "QSQLITE") && (!createBmisurveyDatabase(driver))) {
        QMessageBox::critical(0, tr("Critical"), tr("Unable to create bmisurvey database."), QMessageBox::Ok);
        result = false;
    }
    QHash<QString, QString> name_sql;
        name_sql.insert("Table nameindex",
                    "CREATE TABLE IF NOT EXISTS	nameindex ("
                    "id_nameindex  INTEGER PRIMARY KEY,"
                    "patient_uuid varchar(40) NOT NULL,"
                    "name 	    varchar(50)    NOT NULL,"
                    "firstname      varchar(50)   NOT NULL,"
                    "date_of_birth  date   NOT NULL,"
                    "gender         varchar(5) NULL);");
        name_sql.insert("Table weight and height",
                    "CREATE TABLE IF NOT EXISTS	weight_height ("
                    "id_wh INTEGER PRIMARY KEY,"
                    "patient_uuid varchar(40)    NOT NULL,"
                    "weight varchar(10) NULL,"
                    "height varchar(10) NULL,"
                    "input_date date NULL);");


    // Mass execute SQL queries
    QSqlDatabase db = QSqlDatabase::database(Constants::DATABASE_BMISURVEY);
    if ((!db.isOpen()) && (!db.open())) {
            qWarning() << "Unable to create bmisurvey database, database can not be open. " 
                       << __FILE__ << QString::number(__LINE__) ;
        result = false;
    }
    qDebug() << "Hash Size "+QString::number(name_sql.size());
    QHashIterator<QString, QString> it(name_sql);
     while (it.hasNext()) {
         it.next();
         QSqlQuery q(db);
         QString req = it.value();
         q.exec(req);
         // Is there an error with this req ?
         if (q.lastError().isValid()) {
             QMessageBox::warning(qApp->activeWindow(),
                                  tr("Fatal error"),
                                  tr("An error occured during bmisurvey database creation.\n"
                                     "Reference : %1\n"
                                     "Error : %2\n\n"
                                     "Application will not work.")
                                  .arg(it.key()).arg(q.lastError().text()),
                                  QMessageBox::Abort);
                 qWarning() << "SQL Error" << it.key() << q.lastError().text();
             result = false;
         }
     }

    if (result)
    {
    	     QMessageBox mess;
               mess.setText(trUtf8("La base bmisurvey a été installée "));
               mess.setStandardButtons(QMessageBox::Close);
               mess.setDefaultButton(QMessageBox::Close);
               mess.exec();
        }

    return result;
}


